package com.cizzy.comment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cizzy.comment.CommentServerApplication;
import com.cizzy.comment.common.Result;
import com.cizzy.comment.entity.dao.CommentDAO;
import com.cizzy.comment.entity.dao.VideoCountDAO;
import com.cizzy.comment.entity.dto.CommentDTO;
import com.cizzy.comment.entity.vo.CommentRequest;
import com.cizzy.comment.feign.VideoFeign;
import com.cizzy.comment.mapper.CommentMapper;
import com.cizzy.comment.service.ICommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.List;
import java.util.stream.Collectors;

import static com.cizzy.comment.config.CizzyFinal.COMMENT_LOCK;
import static com.cizzy.comment.config.CizzyFinal.PAGE_SIZE;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author terry
 * @since 2023-11-04
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, CommentDAO> implements ICommentService {

    @Autowired
    private CommentMapper commentMapper;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private VideoFeign videoFeign;

    private Result<List<CommentDTO>> getCommentListResult(QueryWrapper<CommentDAO> queryWrapper) {
        List<CommentDAO> comments = commentMapper.selectList(queryWrapper);
        if(comments == null) {
            return Result.error("未读取到视频列表");
        }
        List<CommentDTO> commentListDTO = comments.stream().map(comment -> {
            CommentDTO commentDTO = new CommentDTO();
            commentDTO.convertFromCommentDAO(comment);
            return commentDTO;
        }).collect(Collectors.toList());
        return Result.success(commentListDTO);
    }

    @Override
    public Result<List<CommentDTO>> getCommentListByVideoId(CommentRequest commentRequest) {
        Long videoId = commentRequest.getVideoId();
        if (videoId == null) {
            return Result.error("请求参数为空");
        }
        QueryWrapper<CommentDAO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("video_id", videoId);
        return getCommentListResult(queryWrapper);
    }

    @Override
    public Result<List<CommentDTO>> getCommentPageByVideoId(CommentRequest commentRequest) {
        Long videoId = commentRequest.getVideoId();
        Integer page = commentRequest.getPage();
        if (videoId == null || page == null) {
            return Result.error("请求参数为空");
        }
        QueryWrapper<CommentDAO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("video_id", videoId).
                last(String.format("LIMIT %d,%d", (page-1) * PAGE_SIZE, page * PAGE_SIZE));
        return getCommentListResult(queryWrapper);
    }

    @Override
    public Result<List<CommentDTO>> getCommentListByParentCommentId(CommentRequest commentRequest) {
        Long parentCommentId = commentRequest.getParentCommentId();
        if (parentCommentId == null) {
            return Result.error("请求参数为空");
        }
        QueryWrapper<CommentDAO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_comment_id", parentCommentId);
        return getCommentListResult(queryWrapper);
    }

    @Override
    public Result<List<CommentDTO>> getCommentPageByParentCommentId(CommentRequest commentRequest) {
        Long parentCommentId = commentRequest.getParentCommentId();
        Integer page = commentRequest.getPage();
        if (parentCommentId == null || page == null) {
            return Result.error("请求参数为空");
        }
        QueryWrapper<CommentDAO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_comment_id", parentCommentId).
                last(String.format("LIMIT %d,%d", (page-1) * PAGE_SIZE, page * PAGE_SIZE));
        return getCommentListResult(queryWrapper);
    }

    @Override
    public Result<CommentDAO> getCommentByCommentId(Long commentId) {
        CommentDAO comment = commentMapper.selectById(commentId);
        return Result.success(comment);
    }

    @GlobalTransactional
    @Override
    public synchronized Result<CommentDAO> createComment(CommentDAO comment) {
        if (comment == null) {
            return Result.error("评论内容为空");
        }
        RLock lock = redissonClient.getLock(COMMENT_LOCK);
        lock.lock();
        comment.setCreateAt(new Timestamp(System.currentTimeMillis()));
        int result = commentMapper.insert(comment);
        VideoCountDAO videoCount = null;
        if (result > 0) {
            videoCount = videoFeign.addVideoCountById("comment_count", comment.getVideoId(), 1).getData();
        }
        lock.unlock();
        if (videoCount == null) {
            return Result.error("评论创建失败");
        }
        return Result.success(comment);
    }

    @GlobalTransactional
    @Override
    public synchronized Result<CommentDAO> deleteCommentById(Long commentId) {
        if (commentId == null) {
            return Result.error("评论id为空");
        }
        RLock lock = redissonClient.getLock(COMMENT_LOCK);
        lock.lock();
        CommentDAO comment = commentMapper.selectById(commentId);
        int result = commentMapper.deleteById(commentId);
        VideoCountDAO videoCount = null;
        if (result > 0) {
            videoCount = videoFeign.addVideoCountById("comment_count", comment.getVideoId(), -1).getData();
        }
        lock.unlock();
        if (videoCount == null) {
            return Result.error("评论删除失败");
        }
        return Result.success(comment);
    }

    @Override
    public synchronized Result<CommentDAO> deleteChildrenComment(Long commentId) {
        QueryWrapper<CommentDAO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_comment_id", commentId);
        int result = commentMapper.delete(queryWrapper);
        if (result > 0) {
            return Result.success();
        } else {
            return Result.error("评论删除失败");
        }
    }

    @Override
    public Result<List<CommentDTO>> getBulletChatCommentList(CommentRequest commentRequest) {
        Long videoId = commentRequest.getVideoId();
        Integer page = commentRequest.getPage();
        if (videoId == null || page == null) {
            return Result.error("视频ID为空");
        }
        QueryWrapper<CommentDAO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("video_id", videoId).
                last(String.format("LIMIT %d,%d", (page-1) * PAGE_SIZE, page * PAGE_SIZE));
        List<CommentDAO> comments = commentMapper.selectList(queryWrapper);
        if (comments == null) {
            return Result.error("未读取到评论列表");
        }
        List<CommentDTO> commentListDTO = comments.stream().map(comment -> {
            CommentDTO commentDTO = new CommentDTO();
            commentDTO.convertFromCommentDAO(comment);
            return commentDTO;
        }).collect(Collectors.toList());
        return Result.success(commentListDTO);
    }
}
